local extension = Package("ling5")
extension.extensionName = "lingling"

local U = require "packages/utility/utility"
local LUtil = require "packages/lingling/utility/ling_util"

local duguqieluo = General(extension, "lingling__duguqieluo", "sui", 3, 3, General.Female)
local tingzheng = fk.CreateTriggerSkill{
  name = "lingling__tingzheng",
  anim_type = "control",
  events = {fk.AfterCardTargetDeclared},
  can_trigger = function(self, event, target, player, data)
    return target ~= player and player:hasSkill(self) and data.card.type == Card.TypeTrick and data.tos and
      #player:getCardIds("he") >= player:usedSkillTimes(self.name, Player.HistoryRound)
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local n = player:usedSkillTimes(self.name, Player.HistoryRound) + (#room.alive_players < 5 and 1 or 0)
    room:setPlayerMark(player, "lingling__tingzheng-tmp", {TargetGroup:getRealTargets(data.tos), room:getUseExtraTargets(data)})
    local success, dat = room:askForUseActiveSkill(player, "lingling__tingzheng_active",
      "#lingling__tingzheng-choose:::"..n..":"..data.card:toLogString(), true, nil, false)
    room:setPlayerMark(player, "lingling__tingzheng-tmp", 0)
    if success and dat then
      self.cost_data = {tos = dat.targets, cards = dat.cards}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    if #self.cost_data.cards > 0 then
      player.room:throwCard(self.cost_data.cards, self.name, player, player)
    end
    if table.contains(TargetGroup:getRealTargets(data.tos), self.cost_data.tos[1]) then
      TargetGroup:removeTarget(data.tos, self.cost_data.tos[1])
    else
      table.insert(data.tos, self.cost_data.tos)
    end
  end,
}
local tingzheng_active = fk.CreateActiveSkill{
  name = "lingling__tingzheng_active",
  card_num = function ()
    return player:usedSkillTimes("lingling__tingzheng", Player.HistoryRound) + (#Fk:currentRoom().alive_players < 5 and 1 or 0)
  end,
  target_num = 1,
  card_filter = function(self, player, to_select, selected)
    return #selected < player:usedSkillTimes("lingling__tingzheng", Player.HistoryRound) +
      (#Fk:currentRoom().alive_players < 5 and 1 or 0) and
      not player:prohibitDiscard(to_select)
  end,
  target_filter = function (self, player, to_select, selected)
    if #selected == 0 then
      local mark = player:getMark("lingling__tingzheng-tmp")
      return table.contains(mark[1], to_select) or table.contains(mark[2], to_select)
    end
  end,
  target_tip = function(self, to_select, selected, selected_cards, card, selectable, extra_data)
    local mark = player:getMark("lingling__tingzheng-tmp")
    if table.contains(mark[1], to_select) then
      return { {content = "@@CancelTarget", type = "warning"} }
    elseif table.contains(mark[2], to_select) then
      return { {content = "@@AddTarget", type = "normal"} }
    end
  end,
}
local huanchao = fk.CreateTriggerSkill{
  name = "lingling__huanchao",
  anim_type = "control",
  events = {fk.DamageCaused},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target and player:usedSkillTimes(self.name, Player.HistoryRound) == 0
  end,
  on_cost = function (self, event, target, player, data)
    if player.room:askForSkillInvoke(player, self.name, nil, "#lingling__huanchao-invoke:"..target.id..":"..data.to.id) then
      self.cost_data = {tos = {target.id}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    data.damage = data.damage - 1
    room:addPlayerMark(target, "@lingling__huanchao-turn", 1)
    room:addTableMark(player, "lingling__huanchao-turn", target.id)
    player:drawCards(1, self.name)
  end,

  on_lose = function (self, player, is_death)
    if is_death and player:getMark("lingling__huanchao-turn") ~= 0 then
      local room = player.room
      for _, id in ipairs(player:getTableMark("lingling__huanchao-turn")) do
        local p = room:getPlayerById(id)
        room:removePlayerMark(p, "@lingling__huanchao-turn", 1)
      end
    end
  end,
}
local huanchao_delay = fk.CreateTriggerSkill{
  name = "#lingling__huanchao_delay",
  priority = 2,
  anim_type = "offensive",
  events = {fk.DamageCaused},
  can_trigger = function (self, event, target, player, data)
    return target and table.contains(player:getTableMark("lingling__huanchao-turn"), target.id)
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark("lingling__huanchao-turn")
    for i = #mark, 1, -1 do
      if target.dead or player.dead then return end
      if mark[i] == target.id then
        data.damage = data.damage + 1
        room:removePlayerMark(target, "@lingling__huanchao-turn", 1)
        table.remove(mark, i)
        if not player:isNude() then
          if target == player then
            room:askForDiscard(player, 1, 1, true, "lingling__huanchao", false, nil, "#lingling__huanchao-discard:"..player.id)
          else
            local card = room:askForCardChosen(target, player, "he", "lingling__huanchao", "#lingling__huanchao-discard:"..player.id)
            room:throwCard(card, "lingling__huanchao", player, target)
          end
        end
      end
    end
    if not player.dead then
      room:setPlayerMark(player, "lingling__huanchao-turn", mark)
    end
  end,
}
Fk:addSkill(tingzheng_active)
huanchao:addRelatedSkill(huanchao_delay)
duguqieluo:addSkill(tingzheng)
duguqieluo:addSkill(huanchao)
Fk:loadTranslationTable{
  ["lingling__duguqieluo"] = "独孤伽罗",
  ["#lingling__duguqieluo"] = "一代贤后",
  ["designer:lingling__duguqieluo"] = "伶",
  ["illustrator:lingling__duguqieluo"] = "伊达未来",

  ["lingling__tingzheng"] = "听政",
  [":lingling__tingzheng"] = "其他角色使用锦囊牌指定目标时，你可以弃置X张牌（X为本轮已发动次数，若存活人数少于5则X初始+1）使之多指定一个目标或"..
  "取消一个目标。",
  ["lingling__huanchao"] = "缓朝",
  [":lingling__huanchao"] = "每轮限一次，当一名角色造成伤害时，你可以摸一张牌令伤害-1，则其本回合下一次造成伤害时弃置你一张牌令伤害+1。"..
  "<br><br> <font color='#a40000'>贵戚之盛，莫与为比。谦卑自守，世以为贤。",
  ["lingling__tingzheng_active"] = "听政",
  ["#lingling__tingzheng-choose"] = "听政：你可以弃置%arg张牌，为%arg2增加或取消一个目标",
  ["#lingling__huanchao-invoke"] = "缓朝：%src 对 %dest 造成伤害，是否摸一张牌令伤害-1？其下一次伤害+1并弃置你一张牌",
  ["@lingling__huanchao-turn"] = "造成伤害+",
  ["#lingling__huanchao_delay"] = "缓朝",
  ["#lingling__huanchao-discard"] = "缓朝：弃置 %src 一张牌",
}

local gaojiong = General(extension, "lingling__gaojiong", "sui", 3, 5)
--[[local shuchen = fk.CreateTriggerSkill{
  name = "lingling__shuchen",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and data.card.type == Card.TypeTrick then
      local turn_event = player.room.logic:getCurrentEvent():findParent(GameEvent.Turn)
      if turn_event and turn_event.data[1] == player then
        local n = #player.room.logic:getEventsOfScope(GameEvent.UseCard, 999, function(e)
          return e.data[1].from == player.id
        end, Player.HistoryTurn)
        if n == #table.filter(player.player_skills, function (s)
          return s:isPlayerSkill(player) and s.visible
        end) then
          self.cost_data = n
          return true
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(self.cost_data, self.name)
  end,

  refresh_events = {fk.AfterCardUseDeclared},
  can_refresh = function (self, event, target, player, data)
    return target == player and player:hasSkill(self, true) and data.card.type == Card.TypeTrick
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    local turn_event = player.room.logic:getCurrentEvent():findParent(GameEvent.Turn)
    if turn_event and turn_event.data[1] == player then
      room:addPlayerMark(player, "@lingling__shuchen-turn", 1)
    end
  end,
}]]--
local shuchen = fk.CreateTriggerSkill{
  name = "lingling__shuchen",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.RoundStart},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if player.room:getBanner("RoundCount") == 1 then
        return true
      elseif player.room:getBanner("RoundCount") == 2 then
        return player.shield > 0
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if room:getBanner("RoundCount") == 1 then
      room:changeShield(player, 2)
    else
      room:changeShield(player, -2)
    end
  end,
}
local juxian = fk.CreateTriggerSkill{
  name = "lingling__juxian",
  anim_type = "special",
  events = {fk.GameStart, fk.TurnStart},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.GameStart then
        return true
      elseif event == fk.TurnStart then
        return target == player
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local skills = LUtil.GetRandomSkills(player, 3)
    if #skills == 0 then return end
    local result = player.room:askForCustomDialog(player, self.name,
      "packages/utility/qml/ChooseSkillBox.qml", {
        skills, 0, 1, "#lingling__juxian-choice", {},
      })
    if result ~= "" and #json.decode(result) > 0 then
      self.cost_data = {choice = json.decode(result)[1]}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, self.name, self.cost_data.choice)
    room:handleAddLoseSkills(player, self.cost_data.choice, nil, true, false)
  end,
}
local juxian_delay = fk.CreateTriggerSkill{
  name = "#lingling__juxian_delay",
  mute = true,
  priority = 2,
  events = {fk.TurnStart},
  can_trigger = function (self, event, target, player, data)
    return target == player and player:getMark("lingling__juxian") ~= 0
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local skill = player:getMark("lingling__juxian")
    room:setPlayerMark(player, "lingling__juxian", 0)
    if not player:hasSkill(skill, true) then return end
    if room:askForSkillInvoke(player, "lingling__juxian", nil, "#lingling__juxian-ask:::"..skill) then
      room:changeMaxHp(player, -1)
    else
      room:handleAddLoseSkills(player, "-"..skill, nil, true, false)
    end
  end,
}
juxian:addRelatedSkill(juxian_delay)
gaojiong:addSkill(shuchen)
gaojiong:addSkill(juxian)
Fk:loadTranslationTable{
  ["lingling__gaojiong"] = "高颎",
  ["#lingling__gaojiong"] = "天降良辅",
  ["designer:lingling__gaojiong"] = "伶",
  ["illustrator:lingling__gaojiong"] = "伊达未来",

  ["lingling__shuchen"] = "枢臣",
  --[":lingling__shuchen"] = "你回合内，当你本回合第X次使用锦囊牌结算后，你摸X张牌（X为你的技能数）。",
  [":lingling__shuchen"] = "第一轮开始时，你加2点护甲，第二轮开始时失去。",
  ["lingling__juxian"] = "举贤",
  [":lingling__juxian"] = "游戏开始时和回合开始时，你可以从随机三个技能里选择一个获得，下回合开始时你选择：失去之；减1点体力上限使之永久保留。"..
  "<br><br> <font color='#a40000'>抗节不阿，矫枉无挠。",
  --["@lingling__shuchen-turn"] = "枢臣",
  ["#lingling__juxian-choice"] = "举贤：你可以获得其中一个技能直到下回合开始",
  ["#lingling__juxian-ask"] = "举贤：是否减1点体力上限保留“%arg”？",
}

local zhangsunsheng = General(extension, "lingling__zhangsunsheng", "sui", 3, 5)
local fenhua = fk.CreateTriggerSkill{
  name = "lingling__fenhua",
  anim_type = "masochism",
  events = {fk.Damaged},
  can_trigger = function (self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.from and not data.from.dead and
      player:usedSkillTimes(self.name, Player.HistoryTurn) == 0 and
      table.find(player.room.alive_players, function (p)
        return player:inMyAttackRange(p)
      end)
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local cards = table.filter(player:getCardIds("he"), function (id)
      return not player:prohibitDiscard(id)
    end)
    local targets = table.filter(room.alive_players, function (p)
      return player:inMyAttackRange(p)
    end)
    local to, id
    if player:isNude() then
      to = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, "#lingling__fenhua-choose2::"..data.from.id, self.name, true)
    else
      to, id = room:askForChooseCardAndPlayers(player, table.map(targets, Util.IdMapper), 1, 1, tostring(Exppattern{ id = cards }),
      "#lingling__fenhua-choose::"..data.from.id, self.name, true, false)
    end
    if #to > 0 then
      self.cost_data = {tos = to, cards = {id}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if #self.cost_data.cards==0 then
      player:drawCards(1, self.name)
      room:askForDiscard(player, 1, 1, true, self.name, false)
    else
      room:throwCard(self.cost_data.cards, self.name, player, player)
    end
    local to = room:getPlayerById(self.cost_data.tos[1])
    if not to.dead then
      room:damage{
        from = data.from,
        to = to,
        damage = 1,
        skillName = self.name,
      }
    end
  end,
}
local weiwai = fk.CreateTriggerSkill{
  name = "lingling__weiwai",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.Death},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:isWounded()
  end,
  on_use = function (self, event, target, player, data)
    player:drawCards(player:getLostHp(), self.name)
    if not player.dead then
      player.room:changeMaxHp(player, -1)
    end
  end,
}
local weiwai_attackrange = fk.CreateAttackRangeSkill{
  name = "#lingling__weiwai_attackrange",
  frequency = Skill.Compulsory,
  main_skill = weiwai,
  correct_func = function (self, from, to)
    if from:hasSkill(weiwai) and from:isWounded() then
      return from:getLostHp()
    end
    return 0
  end,
}
local weiwai_maxcards = fk.CreateMaxCardsSkill{
  name = "#lingling__weiwai_maxcards",
  frequency = Skill.Compulsory,
  main_skill = weiwai,
  correct_func = function(self, player)
    if player:hasSkill(weiwai) and player:isWounded() then
      return player:getLostHp()
    end
  end,
}
local shuangdiao = fk.CreateTriggerSkill{
  name = "lingling__shuangdiao",
  anim_type = "offensive",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.phase == Player.Play and player:inMyAttackRange(target)
  end,
  on_cost = function(self, event, target, player, data)
    if player.room:askForSkillInvoke(player, self.name, nil, "#lingling__shuangdiao-invoke::"..target.id) then
      self.cost_data = {tos = {target.id}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local use = room:askForUseCard(target, self.name, "slash", "#lingling__shuangdiao-use:"..player.id, true,
    {
      bypass_distances = true,
      bypass_times = true,
      extraUse = true,
      must_targets = {player.id},
    })
    if use then
      use.extraUse = true
      room:useCard(use)
      if not player.dead and not target.dead then
        room:addTableMark(target, "lingling__shuangdiao-turn", player.id)
      end
    else
      local success, dat = room:askForUseActiveSkill(player, "lingling__shuangdiao_viewas",
        "#lingling__shuangdiao-slash::"..target.id, true, {
          bypass_distances = true,
          bypass_times = true,
          extraUse = true,
          must_targets = {target.id},
        })
      if success and dat then
        room:sortPlayersByAction(dat.targets)
        room:useVirtualCard("slash", dat.cards, player, table.map(dat.targets, Util.Id2PlayerMapper), self.name)
      end
    end
  end,
}
local shuangdiao_viewas = fk.CreateViewAsSkill{
  name = "lingling__shuangdiao_viewas",
  card_filter = function (self, player, to_select, selected)
    return #selected == 0
  end,
  view_as = function(self, player, cards)
    if #cards ~= 1 then return end
    local card = Fk:cloneCard("slash")
    card.skillName = "lingling__shuangdiao"
    card:addSubcard(cards[1])
    return card
  end,
}
local shuangdiao_targetmod = fk.CreateTargetModSkill{
  name = "#lingling__shuangdiao_targetmod",
  extra_target_func = function(self, player, skill, card)
    if card and table.contains(card.skillNames, "lingling__shuangdiao") then
      return 1
    end
  end,
}
local shuangdiao_prohibit = fk.CreateProhibitSkill{
  name = "#shuangdiao_prohibit",
  is_prohibited = function(self, from, to, card)
    return card and card.type == Card.TypeTrick and table.contains(from:getTableMark("lingling__shuangdiao-turn"), to.id)
  end,
}
weiwai:addRelatedSkill(weiwai_attackrange)
weiwai:addRelatedSkill(weiwai_maxcards)
Fk:addSkill(shuangdiao_viewas)
shuangdiao:addRelatedSkill(shuangdiao_targetmod)
shuangdiao:addRelatedSkill(shuangdiao_prohibit)
zhangsunsheng:addSkill(fenhua)
zhangsunsheng:addSkill(weiwai)
zhangsunsheng:addSkill(shuangdiao)
Fk:loadTranslationTable{
  ["lingling__zhangsunsheng"] = "长孙晟",
  ["#lingling__zhangsunsheng"] = "威行逸群",
  ["designer:lingling__zhangsunsheng"] = "伶",
  ["illustrator:lingling__zhangsunsheng"] = "伊达未来",

  ["lingling__fenhua"] = "分化",
  [":lingling__fenhua"] = "每回合限一次，当你受到伤害后，你可以弃置一张牌（若你没有牌你先摸一张牌），令伤害来源对一名你攻击范围内的角色造成1点伤害。",
  ["lingling__weiwai"] = "威外",
  [":lingling__weiwai"] = "你的攻击范围和手牌上限始终+X（X为你已损失体力）。其他角色死亡时，你摸X张牌，然后减1点体力上限。",
  ["lingling__shuangdiao"] = "双雕",
  [":lingling__shuangdiao"] = "你攻击范围内的其他角色出牌阶段开始时，你可以令其选择：你将一张牌当【杀】对其使用，且可以额外指定一个目标；"..
  "对你使用一张无距离次数限制的【杀】，然后本回合不能对你使用锦囊牌。"..
  "<br><br> <font color='#a40000'>体资英武，兼包奇略，因机制变，怀彼戎夷。",
  ["#lingling__fenhua-choose"] = "分化：弃置一张牌，令 %dest 对你指定的角色造成1点伤害",
  ["#lingling__fenhua-choose2"] = "分化：摸一张牌再弃置一张牌，令 %dest 对你指定的角色造成1点伤害",
  ["#lingling__shuangdiao-invoke"] = "双雕：是否令 %dest 选择你对其使用【杀】或其对你使用【杀】？",
  ["#lingling__shuangdiao-use"] = "双雕：对 %src 使用一张【杀】，或点“取消”其可以将一张牌当【杀】对你使用",
  ["lingling__shuangdiao_viewas"] = "双雕",
  ["#lingling__shuangdiao-slash"] = "双雕：将一张牌当【杀】对 %dest 使用，可以额外指定一个目标",
}

local limiw = General(extension, "lingling__limiw", "qun", 4)
local shidu = fk.CreateViewAsSkill{
  name = "lingling__shidu",
  anim_type = "drawcard",
  pattern = "ex_nihilo",
  prompt = "#lingling__shidu",
  card_filter = function(self, player, to_select, selected)
    return #selected == 0 and table.contains({"analeptic"}, Fk:getCardById(to_select).trueName)
  end,
  view_as = function(self, player, cards)
    if #cards ~= 1 then return end
    local card = Fk:cloneCard("ex_nihilo")
    card:addSubcards(cards)
    card.skillName = self.name
    return card
  end,
  enabled_at_response = function (self, player, response)
    return not response
  end,
}
local shidu_trigger = fk.CreateTriggerSkill{
  name = "#lingling__shidu_trigger",
  mute = true,
  frequency = Skill.Compulsory,
  main_skill = shidu,
  events = {fk.DamageCaused, fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(shidu) and data.damage > 1
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("lingling__shidu")
    if data.damage > 1 then
      if event == fk.DamageCaused then
        room:notifySkillInvoked(player, "lingling__shidu", "negative")
      else
        room:notifySkillInvoked(player, "lingling__shidu", "defensive")
      end
      data.damage = 1
    else
      --[[if room:askForSkillInvoke(player, "lingling__shidu", nil, "#lingling__shidu-invoke") then
        room:notifySkillInvoked(player, "lingling__shidu", "drawcard")
        local turn_event = player.room.logic:getCurrentEvent():findParent(GameEvent.Turn)
        if turn_event and turn_event.data[1] == player then
          room:setPlayerMark(player, "lingling__shidu-turn", 1)
        end
        room:changeMaxHp(player, -1)
        if not player.dead then
          player:drawCards(2, "lingling__shidu")
        end
      end]]--
    end
  end,
}
local fanfu = fk.CreateTriggerSkill{
  name = "lingling__fanfu",
  mute = true,
  frequency = Skill.Compulsory,
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if player.phase ~= Player.NotActive and player.phase ~= Player.Draw then
        for _, move in ipairs(data) do
          if move.to == player.id and move.toArea == Card.PlayerHand and move.skillName ~= self.name then
            return true
          end
        end
      elseif player.phase == Player.NotActive and not player:isNude() then
        for _, move in ipairs(data) do
          if move.from == player.id and move.moveReason ~= fk.ReasonUse and move.moveReason ~= fk.ReasonResonpse and
            not (move.skillName and Fk.skills[move.skillName] and
            table.find(player.room.players, function (p)
              return p:hasSkill(move.skillName, true, true)
            end)) then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                return true
              end
            end
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name)
    if player.phase ~= Player.NotActive then
      room:notifySkillInvoked(player, self.name, "drawcard")
      player:drawCards(1, self.name)
    else
      room:notifySkillInvoked(player, self.name, "negative")
      room:askForDiscard(player, 1, 1, true, self.name, false)
    end
  end,
}
local kaicang = fk.CreateActiveSkill{
  name = "lingling__kaicang",
  anim_type = "control",
  card_num = 0,
  target_num = 1,
  prompt = "#lingling__kaicang",
  frequency = Skill.Limited,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, selected_cards)
    local target = Fk:currentRoom():getPlayerById(to_select)
    return #selected == 0 and target:getHandcardNum() > target.hp
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:changeMaxHp(player, -1)
    if player.dead or target.dead then return end
    local n = target:getHandcardNum() - target.hp
    if n > 0 then
      local cards = room:askForCardsChosen(player, target, 1, n, "he", self.name, "#lingling__kaicang-ask::"..target.id..":"..n)
      room:moveCards({
        ids = cards,
        from = target.id,
        toArea = Card.DrawPile,
        moveReason = fk.ReasonPut,
        skillName = self.name,
        moveVisible = false,
        drawPilePosition = 1,
      })
    end
    local card = Fk:cloneCard("amazing_grace")
    card.skillName = self.name
    if player:canUse(card) then
      room:useCard({
        from = player.id,
        card = card,
      })
    end
  end,
}
shidu:addRelatedSkill(shidu_trigger)
limiw:addSkill(shidu)
limiw:addSkill(fanfu)
limiw:addSkill(kaicang)
Fk:loadTranslationTable{
  ["lingling__limiw"] = "李密",
  ["#lingling__limiw"] = "为龙为蛇",
  ["designer:lingling__limiw"] = "伶",
  ["illustrator:lingling__limiw"] = "伊达未来",

  ["lingling__shidu"] = "识度",
  --[[[":lingling__shidu"] = "当你造成或受到伤害时，若伤害大于1则减至1，若伤害为1，你可以减1点体力上限并摸两张牌（你回合内限以此法摸牌一次）。"..
  "你可以将【酒】或【桃】当【无中生有】使用。",]]--
  [":lingling__shidu"] = "当你造成或受到伤害时，若伤害大于1则减至1。你可以将【酒】当【无中生有】使用。",
  ["lingling__fanfu"] = "反复",
  [":lingling__fanfu"] = "你回合内，你不因摸牌阶段和此技能获得牌后，你摸一张牌。你回合外，你不因使用打出牌和角色技能失去牌后，你弃置一张牌。",
  ["lingling__kaicang"] = "开仓",
  [":lingling__kaicang"] = "限定技，出牌阶段，你可以减1点体力上限，将一名手牌多于体力的角色至多X张牌置于牌堆顶（X为其手牌与体力的差值），"..
  "然后你视为使用【五谷丰登】。"..
  "<br><br> <font color='#a40000'>君世素贵，当以才学显，何事三卫间哉！",
  ["#lingling__shidu"] = "识度：你可以将【酒】当【无中生有】使用",
  ["#lingling__kaicang"] = "开仓：减1点体力上限，将一名手牌多于体力角色的牌置于牌堆顶，视为使用【五谷丰登】！",
  ["#lingling__kaicang-ask"] = "开仓：选择 %dest 的至多%arg张牌置于牌堆顶",

  ["$lingling__kaicang1"] = "隋主无道，而天有道！",
  ["$lingling__kaicang2"] = "伪施济难之事，欲取扬名之实！",
}

local heruobi = General(extension, "lingling__heruobi", "sui", 5)
local gongao = fk.CreateTriggerSkill{
  name = "lingling__gongao",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.RoundStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if room:getBanner("RoundCount") == 1 then
      local cards = table.filter(room.draw_pile, function (id)
        local card = Fk:getCardById(id)
        return card.sub_type == Card.SubtypeWeapon and player:canUseTo(card, player)
      end)
      if #cards > 0 then
        room:useCard({
          from = player.id,
          tos = {{player.id}},
          card = Fk:getCardById(table.random(cards))
        })
        if player.dead then return end
      end
      cards = room:getCardsFromPileByRule("slash")
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, true, player.id)
      end
    elseif room:getBanner("RoundCount") > 1 then
      local record = {}
      for _, p in ipairs(room.players) do
        record[p.id] = 0
      end
      local start_id, end_id = 0, 0
      room.logic:getEventsByRule(GameEvent.Round, 1, function (e)
        if e.id ~= room.logic:getCurrentEvent():findParent(GameEvent.Round).id then
          start_id, end_id = e.id, e.end_id
          return true
        end
      end, 1)
      if start_id > 0 then
        room.logic:getEventsByRule(GameEvent.Damage, 1, function (e)
          if e.id <= end_id then
            local damage = e.data[1]
            if damage.from then
              record[damage.from.id] = record[damage.from.id] + damage.damage
            end
          end
        end, start_id)
      end
      local n = record[player.id]
      local yes = true
      for _, num in pairs(record) do
        if num > n then
          yes = false
          break
        end
      end
      room:setPlayerMark(player, yes and "@@lingling__gongao_Inflicted-round" or "@@lingling__gongao_Caused-round", 1)
      room:setPlayerMark(player, yes and "@@lingling__gongao1-round" or "@@lingling__gongao2-round", 1)
    end
  end,

  refresh_events = {fk.DrawNCards, fk.DamageInflicted, fk.DamageCaused},
  can_refresh = function (self, event, target, player, data)
    if target == player then
      if player:getMark("@@lingling__gongao1-round") > 0 then
        if event == fk.DrawNCards then
          return true
        elseif event == fk.DamageInflicted then
          return #player.room.logic:getEventsOfScope(GameEvent.Damage, 2, function (e)
            return e.data[1].to == player
          end, Player.HistoryRound) == 1
        end
      elseif player:getMark("@@lingling__gongao2-round") > 0 then
        if event == fk.DamageCaused then
          return data.card and data.card.trueName == "slash" and
            #player.room.logic:getActualDamageEvents(1, function (e)
              local damage = e.data[1]
              return damage.from == player and damage.card and damage.card.trueName == "slash"
            end, Player.HistoryRound) == 0
        end
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    if event == fk.DrawNCards then
      data.n = data.n + 2
    else
      data.damage = data.damage + 1
      if event == fk.DamageCaused then
        player.room:removePlayerMark(player, "@@lingling__gongao_Caused-round", 1)
      elseif event == fk.DamageInflicted then
        player.room:removePlayerMark(player, "@@lingling__gongao_Inflicted-round", 1)
      end
    end
  end,
}
local gongao_targetmod = fk.CreateTargetModSkill{
  name = "#lingling__gongao_targetmod",
  residue_func = function(self, player, skill, scope)
    if skill.trueName == "slash_skill" and player:getMark("@@lingling__gongao2-round") > 0 and scope == Player.HistoryPhase then
      return 1
    end
  end,
}
local aozhan = fk.CreateTriggerSkill{
  name = "lingling__aozhan",
  anim_type = "masochism",
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      player:canUse(Fk:cloneCard("slash"), {bypass_distances = true, bypass_times = true})
  end,
  on_cost = function(self, event, target, player, data)
    local use = U.askForUseVirtualCard(player.room, player, "slash", nil, self.name,
      "#lingling__aozhan-invoke", true, true, true, true, nil, true)
    if use then
      self.cost_data = use
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:changeMaxHp(player, -1)
    local use = self.cost_data
    if data.damage > 1 then
      use.extra_data = {
        lingling__aozhan = true,
      }
    end
    room:useCard(use)
  end,

  refresh_events = {fk.TargetSpecified},
  can_refresh = function (self, event, target, player, data)
    return target == player and table.contains(data.card.skillNames, self.name) and data.extra_data and data.extra_data.lingling__aozhan
  end,
  on_refresh = function (self, event, target, player, data)
    data.fixedResponseTimes = data.fixedResponseTimes or {}
    data.fixedResponseTimes["jink"] = 2
  end,
}
gongao:addRelatedSkill(gongao_targetmod)
heruobi:addSkill(gongao)
heruobi:addSkill(aozhan)
Fk:loadTranslationTable{
  ["lingling__heruobi"] = "贺若弼",
  ["#lingling__heruobi"] = "克定三吴",
  ["designer:lingling__heruobi"] = "伶",
  ["illustrator:lingling__heruobi"] = "伊达未来",

  ["lingling__gongao"] = "功傲",
  [":lingling__gongao"] = "第一轮开始时，你随机使用一张武器牌并获得一张【杀】。之后每轮开始时，若你上轮造成的伤害值最多或之一，本轮你摸牌阶段"..
  "多摸两张牌，且本轮首次受到的伤害+1，若不是，本轮你出牌阶段能多使用一张【杀】，且本轮你使用【杀】首次造成的伤害+1。",
  ["lingling__aozhan"] = "鏖战",
  [":lingling__aozhan"] = "当你受到伤害后，你可以减1点体力上限，视为使用一张无距离限制的【杀】，若你受到的伤害大于1，此【杀】须依次使用"..
  "两张【闪】抵消。"..
  "<br><br> <font color='#a40000'>朝臣之内，文武才干，无若贺若弼者。",
  ["@@lingling__gongao1-round"] = "功傲 多摸牌",
  ["@@lingling__gongao2-round"] = "功傲 多出杀",
  ["@@lingling__gongao_Inflicted-round"] = "受到伤害+1",
  ["@@lingling__gongao_Caused-round"] = "杀伤害+1",
  ["#lingling__aozhan-invoke"] = "鏖战：你可以减1点体力上限，视为使用无距离限制的【杀】",
}

local zhangxutuo = General(extension, "lingling__zhangxutuo", "sui", 5)
local jiaokuang = fk.CreateTriggerSkill{
  name = "lingling__jiaokuang",
  anim_type = "switch",
  events = {fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and
      data.card.trueName == "slash" then
      if player:getMark("@lingling__jiaokuang") == "lingling__jiaokuang2" then
        return true
      else
        return not player.room:getPlayerById(data.to).dead
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local prompt = string.sub(player:getMark("@lingling__jiaokuang"), 20)
    if player.room:askForSkillInvoke(player, self.name, nil, "#lingling__jiaokuang"..prompt.."-invoke::"..data.to) then
      self.cost_data = {tos = {data.to}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if not player:isWounded() then
      data.additionalDamage = (data.additionalDamage or 0) + 1
    end
    local to = room:getPlayerById(data.to)
    local choice = player:getMark("@lingling__jiaokuang")
    room:changeMaxHp(player, -1)
    if choice == "lingling__jiaokuang1" then
      if player.dead then return end
      if player:getMark("@lingling__jiaokuang") ~= 0 then
        room:setPlayerMark(player, "@lingling__jiaokuang", "lingling__jiaokuang2")
      end
      if to.dead or to:isNude() then return end
      local cards = room:askForCardsChosen(player, to, math.min(#target:getCardIds("he"), 2), 2, "he", self.name,
        "#lingling__jiaokuang-discard::"..to.id)
      room:throwCard(cards, self.name, to, player)
    elseif choice == "lingling__jiaokuang2" then
      if player.dead then return end
      if player:getMark("@lingling__jiaokuang") ~= 0 then
        room:setPlayerMark(player, "@lingling__jiaokuang", "lingling__jiaokuang3")
      end
      player:drawCards(2, self.name)
    elseif choice == "lingling__jiaokuang3" then
      if not player.dead and player:getMark("@lingling__jiaokuang") ~= 0 then
        room:setPlayerMark(player, "@lingling__jiaokuang", "lingling__jiaokuang1")
      end
      if to.dead then return end
      to:drawCards(2, self.name)
      if to.dead then return end
      to:turnOver()
    end
  end,

  on_acquire = function (self, player, is_start)
    player.room:setPlayerMark(player, "@lingling__jiaokuang", "lingling__jiaokuang1")
  end,
  on_lose = function (self, player, is_death)
    player.room:setPlayerMark(player, "@lingling__jiaokuang", 0)
  end,
}
local leigong = fk.CreateTriggerSkill{
  name = "lingling__leigong",
  anim_type = "support",
  frequency = Skill.Compulsory,
  events = {fk.Deathed},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and data.damage and data.damage.from and data.damage.from == player
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:changeMaxHp(player, 2)
    if player:isWounded() and not player.dead then
      room:recover{
        who = player,
        num = math.min(player.maxHp - player.hp, 2),
        recoverBy = player,
        skillName = self.name,
      }
    end
  end,
}
zhangxutuo:addSkill(jiaokuang)
zhangxutuo:addSkill(leigong)
Fk:loadTranslationTable{
  ["lingling__zhangxutuo"] = "张须陀",
  ["#lingling__zhangxutuo"] = "蹈义扬烈",
  ["designer:lingling__zhangxutuo"] = "伶",
  ["illustrator:lingling__zhangxutuo"] = "珊瑚虫",

  ["lingling__jiaokuang"] = "骄狂",
  [":lingling__jiaokuang"] = "转换技，当你使用【杀】指定目标后，你可以减1点体力上限并：①弃置其两张牌；②摸两张牌；③令其摸两张牌并翻面。"..
  "若你因减体力上限失去了体力，则此【杀】造成的伤害+1。",
  ["lingling__leigong"] = "累功",
  [":lingling__leigong"] = "当你杀死一名角色后，你加2点体力上限并回复2点体力。"..
  "<br><br> <font color='#a40000'>荣高八使，位隆三独。既赖分茅，终期戬国。",
  ["#lingling__jiaokuang1-invoke"] = "骄狂：是否减1点体力上限并弃置 %dest 两张牌？",
  ["#lingling__jiaokuang2-invoke"] = "骄狂：是否减1点体力上限并摸两张牌？",
  ["#lingling__jiaokuang3-invoke"] = "骄狂：是否减1点体力上限并令 %dest 摸两张牌且翻面？",
  ["#lingling__jiaokuang-discard"] = "骄狂：弃置 %dest 两张牌",
  ["@lingling__jiaokuang"] = "骄狂",
  ["lingling__jiaokuang1"] = "弃牌",
  ["lingling__jiaokuang2"] = "摸牌",
  ["lingling__jiaokuang3"] = "翻面",
}

return extension
